// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

import { PageViewTypeId, PageViewPath, PageOutEffect, PageCloseEffect } from '../define/PageDefine';
import { PageOutEffectType } from '../define/PageEffect';
import { EaseType } from '../define/Ease';
import GameSet from '../define/GameSet';

const { ccclass, property } = cc._decorator;

@ccclass
export default class PageBaseView extends cc.Component {
  // LIFE-CYCLE CALLBACKS:

  // onLoad () {}

  start() {}

  public async closeView(view: PageViewTypeId) {
    let showView: any = await this.getCacheView(view, true);
    if (!showView) {
      console.log('关闭不存在页面' + view);
      return;
    }
    let zType: number = showView.getComponent(view).zType;
    showView.getComponent(view).onHide();

    //执行一些动画
    if (PageCloseEffect[view]) {
      this.playCloseEft(showView, PageCloseEffect[view]);
    }

    if (showView.parent) {
      showView.removeFromParent(false);
      if (this.viewList[zType]) delete this.viewList[zType];
    }
  }

  public async closeAll() {
    for (let i: number = 0; i < this.viewList.length; i++) {
      let showView: any = this.viewList[i];
      if (showView && showView.parent) {
        showView.removeFromParent(false);
      }
    }
    this.viewList = [];
  }

  public async openView(view: PageViewTypeId, data: any = null) {
    if (!this.viewList) {
      this.viewList = [];
      this.viewGather = {};
    }
    let showView: any = await this.getCacheView(view);
    if (!showView) {
      console.log('打开不存在页面' + view);
      return;
    }
    let script: any = showView.getComponent(view);
    if (script) {
      let zType: number = script.zType;
      if (zType || zType == 0) {
        await this.removeUpPage(showView, zType);
        if (!this.viewList[zType]) this.viewList[zType] = showView;
      }
      if (data) {
        script.onShow(data);
      } else {
        script.onShow();
      }
      script.viewName = view;
    } else {
      console.log(`页面${view}没有配置脚本`);
    }
    this.node.addChild(showView);
    //执行一些动画
    if (PageOutEffect[view]) {
      this.playOpenEft(showView, PageOutEffect[view], script);
    }
  }

  //运行某个页面的方法
  public runViewFunc(view: string, funcName: string, paras: any = null): void {
    let showView: any = this.viewGather[view];
    if (!showView) {
      console.log('运行尚未打开的页面方法' + view + '--' + funcName + '--' + paras);
      return;
    }
    if (showView.getComponent(view)[funcName]) {
      if (paras) {
        showView.getComponent(view)[funcName](paras);
      } else {
        showView.getComponent(view)[funcName]();
      }
    } else {
      console.log('页面不存在方法' + view + '--' + funcName + '--' + paras);
    }
  }

  //移除上层的页面
  private async removeUpPage(view: any, zType = 1) {
    let ztype: number = zType;
    for (let i: number = this.viewList.length - 1; i >= 0; i--) {
      let upview: any = this.viewList[i];
      if (upview && i >= ztype) {
        if (upview.name) {
          await this.closeView(upview.name);
          delete this.viewList[i];
        }
      }
    }
  }

  //从缓存里取出页面
  public viewList: any[];
  private viewGather: any;
  private async getCacheView(viewName: PageViewTypeId, fromCache: boolean = false) {
    if (this.viewGather[viewName]) {
      return this.viewGather[viewName];
    }
    if (fromCache) return null; //如果必须从缓存里取但是又没有的情况
    let viewIns: any = await this.newPrefab(viewName);
    this.viewGather[viewName] = viewIns;
    return viewIns;
  }

  private async newPrefab(viewName: PageViewTypeId) {
    return new Promise((resolve, reject) => {
      let path: PageViewPath = PageViewPath[viewName];
      cc.loader.loadRes(path, (err: Error, prefab: any) => {
        var prefab = cc.instantiate(prefab);
        return resolve(prefab);
        //this.node.addChild(prefab);
      });
    });
  }

  /**
   * 播放打开动画
   */
  private playOpenEft(node: cc.Node, eft: PageOutEffect, script: any): void {
    let type: number = <any>eft;
    let props: any = {},
      duration: number = 0,
      ease: any = null;

    switch (type) {
      // 没有动画
      case PageOutEffectType.NONE:
        break;
      // 从右边渐入
      case PageOutEffectType.UNFOLD_LEFT:
        node.x = GameSet.designWidth;
        props = { x: 0 };
        duration = 0.2;
        ease = { easing: EaseType.quadOut };
        break;
      // 向上展开动画
      case PageOutEffectType.UNFOLD_UP:
        node.y = -GameSet.designHeight;
        props = { y: 0 };
        duration = 0.2;
        // egret.Tween.get(this.uiObject).to({ y: 0 }, 500, null);
        break;
      // 中间弹出动画
      case PageOutEffectType.CENTER_ZOOM_OUT:
        node.scale = 0.5;
        props = { scale: 1, x: 0, y: 0 };
        duration = 0.2;
        ease = { easing: EaseType.backOut };
        // egret.Tween.get(this.uiObject).to({ scaleX: 1, scaleY: 1, x: 0, y: 0 }, 500, egret.Ease.backOut);
        break;
      // 中间平移向下
      case PageOutEffectType.CENTER_TRANSLATE_BOTTOM:
        node.y = 100;
        node.opacity = 150;
        props = { scale: 1, x: 0, y: 0, opacity: 255 };
        duration = 0.2;
        ease = { easing: EaseType.cubicOut };
        //ease = egret.Ease.cubicOut;
        // egret.Tween.get(this.uiObject).to({ scaleX: 1, scaleY: 1, x: 0, y: uiObjectY, alpha: 1 }, 500, egret.Ease.cubicOut);
        break;
    }

    cc.tween(node)
      .to(duration, props, ease)
      .call(() => {
        if (script && script.onPlayOpenEftOver) {
          script.onPlayOpenEftOver();
        }
      })
      .start();
    //egret.Tween.get(this.uiObject).to(props, duration, ease).call(this.$onOpenAniDone.bind(this));
  }

  /**
   * 播放关闭动画
   */
  private playCloseEft(node: cc.Node, eft: PageCloseEffect): void {}

  // update (dt) {}
}
